import { useScrollToTop } from "@react-navigation/native";
import { Stack, useFocusEffect } from "expo-router";
import React, { useCallback, useMemo, useRef, useState } from "react";
import { Platform, RefreshControl } from "react-native";
import { FlatList } from "react-native-gesture-handler";
import Animated, {
  useAnimatedScrollHandler,
  useAnimatedStyle,
  useSharedValue,
  interpolate,
  Extrapolation,
} from "react-native-reanimated";

import { ActivityCard } from "@/components/ActivityCard";
import { NotFound } from "@/components/NotFound";
import { TalkCard } from "@/components/TalkCard";
import { ConferenceDay } from "@/consts";
import { useReactConfStore } from "@/store/reactConfStore";
import { DayPicker } from "@/components/DayPicker";
import { useThemeColor } from "@/components/Themed";
import { theme } from "@/theme";
import { Session } from "@/types";
import { isLiquidGlassAvailable } from "expo-glass-effect";
import { getInitialDay } from "@/utils/formatDate";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import {
  CurrentlyLive,
  type CurrentlyLiveSession,
} from "@/components/CurrentlyLive";

const AnimatedFlatList = Animated.FlatList;

const HEADER_SCROLL_OFFSET = isLiquidGlassAvailable() ? 110 : 90;

export default function Schedule() {
  const [selectedDay, setSelectedDay] = useState(getInitialDay());
  const scrollRef = useRef<FlatList>(null);
  useScrollToTop(scrollRef as any);
  const backgroundColor = useThemeColor(theme.color.background);
  const isLiquidGlass = isLiquidGlassAvailable();
  const [isRefreshing, setIsRefreshing] = useState(false);
  const insets = useSafeAreaInsets();
  const animatedTranslateY = useSharedValue(0);
  const isScrolledDown = useSharedValue(false);

  const scrollHandler = useAnimatedScrollHandler((event) => {
    animatedTranslateY.value = interpolate(
      event.contentOffset.y,
      [-HEADER_SCROLL_OFFSET, 0],
      [0, HEADER_SCROLL_OFFSET],
      Extrapolation.CLAMP,
    );

    isScrolledDown.value = event.contentOffset.y > 10;
  });

  const stickyHeaderStyle = useAnimatedStyle(() => {
    if (Platform.OS !== "ios") {
      return {};
    }

    return {
      transform: [{ translateY: animatedTranslateY.value }],
      backgroundColor: isLiquidGlass ? "transparent" : backgroundColor,
    };
  });

  const renderItem = useCallback(
    ({ item }: { item: Session }) => {
      if (item.isServiceSession) {
        return <ActivityCard session={item} />;
      } else {
        return <TalkCard key={item.id} session={item} day={selectedDay} />;
      }
    },
    [selectedDay],
  );

  const { dayOne, dayTwo } = useReactConfStore((state) => state.schedule);
  const refreshSchedule = useReactConfStore((state) => state.refreshData);
  const data = selectedDay === ConferenceDay.One ? dayOne : dayTwo;

  useFocusEffect(() => {
    refreshSchedule({ ttlMs: 60_000 });
  });

  const handleSelectDay = useCallback(
    (day: ConferenceDay) => {
      setSelectedDay(day);
      if (isScrolledDown.value) {
        scrollRef.current?.scrollToOffset({
          offset: -30 - insets.top,
          animated: true,
        });
      }
    },
    [insets.top, isScrolledDown],
  );

  const renderStickyHeader = useMemo(
    () => (
      <Animated.View style={stickyHeaderStyle}>
        <DayPicker selectedDay={selectedDay} onSelectDay={handleSelectDay} />
      </Animated.View>
    ),
    [handleSelectDay, selectedDay, stickyHeaderStyle],
  );

  if (!dayOne.length || !dayTwo.length) {
    return <NotFound message="Schedule unavailable" />;
  }

  const handleRefreshSchedule = async () => {
    setIsRefreshing(true);
    await Promise.all([
      new Promise((resolve) => setTimeout(resolve, 1000)),
      refreshSchedule(),
    ]);
    setIsRefreshing(false);
  };

  const handleScrollToSession = (currentlyLive: CurrentlyLiveSession) => {
    setSelectedDay(currentlyLive.day);
    setTimeout(() => {
      scrollRef.current?.scrollToIndex({
        index: currentlyLive.sessionIndex,
        animated: true,
        viewOffset: Platform.select({
          android: 50,
          default: isLiquidGlass
            ? isScrolledDown.value
              ? 155
              : 87
            : isScrolledDown.value
              ? 125
              : 120,
        }),
      });
    }, 200);
  };

  return (
    <>
      <Stack.Screen
        options={{
          headerTitle: () => (
            <CurrentlyLive scrollToSession={handleScrollToSession} />
          ),
        }}
      />
      <AnimatedFlatList
        ref={scrollRef}
        refreshControl={
          <RefreshControl
            refreshing={isRefreshing}
            onRefresh={handleRefreshSchedule}
          />
        }
        style={{ backgroundColor }}
        contentContainerStyle={{
          paddingBottom: Platform.select({
            android: 100 + insets.bottom,
            default: 0,
          }),
        }}
        contentInsetAdjustmentBehavior="automatic"
        scrollToOverflowEnabled
        onScroll={scrollHandler}
        data={data}
        ListHeaderComponent={renderStickyHeader}
        stickyHeaderIndices={[0]}
        keyExtractor={(item: Session) => item.id}
        renderItem={renderItem}
      />
    </>
  );
}
